home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC]
/
NeXTSTEP 3.3 Dev Intel.iso
/
NextDeveloper
/
Source
/
GNU
/
emacs
/
src
/
macros.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-29
|
7KB
|
244 lines
/* Keyboard macros.
Copyright (C) 1985, 1986 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include "lisp.h"
#include "macros.h"
#include "commands.h"
#include "buffer.h"
#include "window.h"
int defining_kbd_macro;
char *kbd_macro_buffer;
char *kbd_macro_ptr;
char *kbd_macro_end;
int kbd_macro_bufsize;
Lisp_Object Vlast_kbd_macro;
Lisp_Object Vexecuting_macro;
int executing_macro_index;
Lisp_Object Fexecute_kbd_macro ();
DEFUN ("start-kbd-macro", Fstart_kbd_macro, Sstart_kbd_macro, 1, 1, "P",
"Record subsequent keyboard input, defining a keyboard macro.\n\
The commands are recorded even as they are executed.\n\
Use \\[end-kbd-macro] to finish recording and make the macro available.\n\
Use \\[name-last-kbd-macro] to give it a permanent name.\n\
Non-nil arg (prefix arg) means append to last macro defined;\n\
This begins by re-executing that macro as if you typed it again.")
(append)
Lisp_Object append;
{
if (defining_kbd_macro)
error ("Already defining kbd macro");
update_mode_lines++;
if (NULL (append))
{
kbd_macro_ptr = kbd_macro_buffer;
kbd_macro_end = kbd_macro_buffer;
message("Defining kbd macro...");
}
else
{
message("Appending to kbd macro...");
kbd_macro_ptr = kbd_macro_end;
Fexecute_kbd_macro (Vlast_kbd_macro, make_number (1));
}
defining_kbd_macro = 1;
return Qnil;
}
DEFUN ("end-kbd-macro", Fend_kbd_macro, Send_kbd_macro, 0, 1, "p",
"Finish defining a keyboard macro.\n\
The definition was started by \\[start-kbd-macro].\n\
The macro is now available for use via \\[call-last-kbd-macro],\n\
or it can be given a name with \\[name-last-kbd-macro] and then invoked\n\
under that name.\n\
With numeric arg, repeat macro now that many times,\n\
counting the definition just completed as the first repetition.")
(arg)
Lisp_Object arg;
{
if (!defining_kbd_macro)
error ("Not defining kbd macro.");
if (NULL (arg))
XFASTINT (arg) = 1;
else
CHECK_NUMBER (arg, 0);
if (defining_kbd_macro)
{
defining_kbd_macro = 0;
update_mode_lines++;
Vlast_kbd_macro = make_string (kbd_macro_buffer,
kbd_macro_end - kbd_macro_buffer);
message("Keyboard macro defined");
}
if (XFASTINT (arg) == 0)
Fexecute_kbd_macro (Vlast_kbd_macro, arg);
else
{
XFASTINT (arg)--;
if (XFASTINT (arg) > 0)
Fexecute_kbd_macro (Vlast_kbd_macro, arg);
}
return Qnil;
}
/* Store character c into kbd macro being defined */
store_kbd_macro_char (c)
unsigned char c;
{
if (defining_kbd_macro)
{
if (kbd_macro_ptr - kbd_macro_buffer == kbd_macro_bufsize)
{
register char *new = (char *) xrealloc (kbd_macro_buffer, kbd_macro_bufsize *= 2);
kbd_macro_ptr += new - kbd_macro_buffer;
kbd_macro_end = new + kbd_macro_bufsize;
kbd_macro_buffer = new;
}
*kbd_macro_ptr++ = c;
}
}
/* Declare that all chars stored so far in the kbd macro being defined
really belong to it. This is done in between editor commands. */
finalize_kbd_macro_chars ()
{
kbd_macro_end = kbd_macro_ptr;
}
DEFUN ("call-last-kbd-macro", Fcall_last_kbd_macro, Scall_last_kbd_macro,
0, 1, "p",
"Call the last keyboard macro that you defined with \\[start-kbd-macro].\n\
To make a macro permanent so you can call it even after\n\
defining others, use \\[name-last-kbd-macro].")
(prefix)
Lisp_Object prefix;
{
if (defining_kbd_macro)
error ("Can't execute anonymous macro while defining one");
else if (NULL (Vlast_kbd_macro))
error ("No kbd macro has been defined");
else
Fexecute_kbd_macro (Vlast_kbd_macro, prefix);
return Qnil;
}
static Lisp_Object
pop_kbd_macro (info)
Lisp_Object info;
{
Lisp_Object tem;
Vexecuting_macro = Fcar (info);
tem = Fcdr (info);
executing_macro_index = XINT (tem);
return Qnil;
}
DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 2, 0,
"Execute MACRO as string of editor command characters.\n\
If MACRO is a symbol, its function definition is used.\n\
COUNT is a repeat count, or nil for once, or 0 for infinite loop.")
(macro, prefixarg)
Lisp_Object macro, prefixarg;
{
Lisp_Object final;
Lisp_Object tem;
int count = specpdl_ptr - specpdl;
int repeat = 1;
struct gcpro gcpro1;
if (!NULL (prefixarg))
prefixarg = Fprefix_numeric_value (prefixarg),
repeat = XINT (prefixarg);
final = macro;
while (XTYPE (final) == Lisp_Symbol && !EQ (final, Qunbound))
final = XSYMBOL (final)->function;
CHECK_STRING (final, 0);
XFASTINT (tem) = executing_macro_index;
tem = Fcons (Vexecuting_macro, tem);
record_unwind_protect (pop_kbd_macro, tem);
GCPRO1 (final);
do
{
Vexecuting_macro = final;
executing_macro_index = 0;
command_loop_1 ();
}
while (--repeat && XTYPE (Vexecuting_macro) == Lisp_String);
UNGCPRO;
unbind_to (count);
return Qnil;
}
init_macros ()
{
Vlast_kbd_macro = Qnil;
defining_kbd_macro = 0;
Vexecuting_macro = Qnil;
}
syms_of_macros ()
{
kbd_macro_bufsize = 100;
kbd_macro_buffer = (char *) malloc (kbd_macro_bufsize);
defsubr (&Sstart_kbd_macro);
defsubr (&Send_kbd_macro);
defsubr (&Scall_last_kbd_macro);
defsubr (&Sexecute_kbd_macro);
DEFVAR_BOOL ("defining-kbd-macro", &defining_kbd_macro,
"Non-nil means store keyboard input into kbd macro being defined.");
DEFVAR_LISP ("executing-macro", &Vexecuting_macro,
"Currently executing keyboard macro (a string); nil if none executing.");
DEFVAR_LISP_NOPRO ("executing-kbd-macro", &Vexecuting_macro,
"Currently executing keyboard macro (a string); nil if none executing.");
DEFVAR_LISP ("last-kbd-macro", &Vlast_kbd_macro,
"Last kbd macro defined, as a string; nil if none defined.");
}
keys_of_macros ()
{
ndefkey (Vctl_x_map, ('e'), "call-last-kbd-macro");
ndefkey (Vctl_x_map, ('('), "start-kbd-macro");
ndefkey (Vctl_x_map, (')'), "end-kbd-macro");
}